#include "Objet.h"

Objet::Objet(){
	reset();
	image = ofImage();
	size = ofVec3f(1,1,1);
	position = ofVec3f(0,0,0);
	rotation = ofVec3f(0,0,0);

	selected = false;
	isMesh = false;
}

void Objet::addPos(float _x, float _y, float _z){
	addPos(ofVec3f(_x, _y, _z));
}

void Objet::addPos(ofVec3f& _vec){
	setPos(getPos() + _vec);
}

void Objet::addPosZ(float _x, float _y, float _z){
	addPosZ(ofVec3f(_x, _y, _z));
}

void Objet::addPosZ(ofVec3f& _vec){
	setPos(getPos() + ofVec3f(_vec.x + _vec.z , _vec.y + _vec.z, _vec.x + _vec.y));
}

void Objet::setPos(float _x, float _y, float _z){
	setPos(ofVec3f(_x, _y, _z));
}

void Objet::setPos(ofVec3f& _vec){
	position = _vec;
}

void Objet::addRot(ofVec3f& _vec){
	setRot(getRot() + _vec);
}

void Objet::setRot(ofVec3f& _vec){
	rotation = _vec;
}

void Objet::setColor(ofColor& _color){
	color = _color;
}

void Objet::setSize(ofVec3f& _size){
	size = _size;
	if(isMesh){
		for(int i=0; i<mesh.getNumVertices(); i++){
			//mesh.setVertex(i, mesh.getVertex(0) * size);
			mesh.setVertex(i, normalMesh.getVertex(i) * size);
		}
	}else{
		xaLoader.setScale(size.x, size.y, size.z);
	}
}

void Objet::setMesh(ofMesh& _mesh){
	normalMesh = mesh = _mesh;
	isMesh = true;
}

void Objet::setImage(ofImage& _image){
	image = _image;
}

void Objet::setSelected(bool _s){
	selected = _s;
	for(list<Objet>::iterator it = enfants.begin(); it != enfants.end(); it++){
		it->setSelected(_s);
	}
}

void Objet::load(string _fileMesh, string _fileImage){
	loadMesh(_fileMesh);
	loadImage(_fileImage);
}

void Objet::load(string _name){
	load(_name + ".ply", _name + ".png");
}

void Objet::loadMesh(string _file){
	xaLoader = ofxAssimpModelLoader();
	xaLoader.loadModel(objPath + _file);
	normalMesh = mesh = xaLoader.getMesh(0);
}

void Objet::loadImage(string _file){
	setImage(ofImage(objPath + _file));
}

void Objet::reset(){
	position = ofVec3f(0,0,0);
	rotation = ofVec3f(0,0,0);
}

ofVec3f& Objet::getPos(){
	return position;
}

ofVec3f& Objet::getRot(){
	return rotation;
}

ofColor& Objet::getColor(){
	return color;
}

ofVec3f& Objet::getSize(){
	return size;
}

ofMesh Objet::getMesh(){
	return mesh;
}

ofMesh Objet::getMesh(int i){
	return isMesh ? mesh : xaLoader.getMesh(i);
}

ofVec3f Objet::getCenter(){
	return (isMesh ? mesh.getCentroid() : xaLoader.getSceneCenter()) + position;
}

Objet * Objet::getPtr(){
	return this;
}

Objet * Objet::click(ofEasyCam _cam, ofVec3f _pos){
	return this;
	/*if(isSelected()){
		return this;
	}else{
		float nearestDistance = 0;
		ofVec2f nearestVertex;
		int nearestIndex = 0;
		ofVec3f cur = _cam.worldToScreen(xaLoader.getMesh(0).getCentroid());
		float distance = cur.distance(_pos);
		if(distance < nearestDistance) {
			nearestDistance = distance;
			nearestVertex = cur;
			nearestIndex = i;
		}
	}*/
}

void Objet::update(){
	for(list<Objet>::iterator it = enfants.begin(); it != enfants.end(); it++){
		it->update();
	}
}

void Objet::draw(){
	ofPushMatrix();
		ofTranslate(position);
		ofRotateX(-rotation.y); ofRotateY(rotation.x); ofRotateZ(rotation.z);
		//image.bind();
		ofSetColor(color);
		if(isMesh) mesh.drawFaces();
		else xaLoader.drawFaces();
		//image.unbind();
		if(selected){
			ofSetColor(color.getInverted());
			ofSetLineWidth(3);
			if(isMesh) mesh.drawWireframe();
			else xaLoader.drawWireframe();
			ofSetLineWidth(1);
		}
		ofSetColor(255,255,255);
		for(list<Objet>::iterator it = enfants.begin(); it != enfants.end(); it++){
			it->draw();
		}
	ofPopMatrix();
}

bool Objet::isMeshSet(){
	return xaLoader.hasMeshes();
}

bool Objet::isSelected(){
	return selected;
}